package transaction.seata.account.service;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import tk.mybatis.mapper.entity.Example;
import transaction.seata.account.mapper.AccountTblMapper;
import transaction.seata.account.model.AccountTbl;

import java.util.List;

@Service
@Slf4j
public class AccountService {

    private static final String ERROR_USER_ID = "1002";

    @Autowired
    private AccountTblMapper accountMapper;

    public void debit(String userId, Integer num) {
        // 第一种写法，不好使，高并发会 产生脏数据
//        synchronized (userId) {
//            AccountTbl account = selectByUserId(userId);
//            assert account != null;
//            account.setMoney(account.getMoney() - (num));
//            if (account.getMoney() < 0) {
//                log.error("账户钱不够了 {},{}", userId, account.getMoney());
//                throw new RuntimeException("账户钱不够了" + userId + ":" + account.getMoney());
//            }
//            accountMapper.updateByPrimaryKeySelectiveNew(account);
//        }

        // 第二种写法
        AccountTbl account = selectByUserId(userId);
        assert account != null;
        int row = accountMapper.updateByPrimaryKeySelectiveNew(account.getId(), num);
        if (row < 1) {
            log.error("账户钱不够了 {},{}", userId, account.getMoney());
            throw new RuntimeException("账户钱不够了" + userId + ":" + account.getMoney());
        }

        if (ERROR_USER_ID.equals(userId)) {
            throw new RuntimeException("account branch exception");
        }
    }

    private AccountTbl selectByUserId(String userId) {
        Example example = new Example(AccountTbl.class);
        example.createCriteria().andEqualTo("userId", userId);
        List<AccountTbl> list = accountMapper.selectByExample(example);
        return CollectionUtils.isEmpty(list) ? null : list.get(0);
    }

}
